import rclpy
from rclpy.node import Node

#1. 导入消息类型
# 从`std_msgs.msg`中导入了String类 UINt32
from std_msgs.msg import String,UInt32

#导入服务接口
#从.srv 中导入 Identify 最好使用 .srv 文件名 Identify 是定义好的接口名
from bot_interface.srv import Identify

"""
创建服务步骤
导入服务接口
创建服务端回调函数
声明并创建服务端
编写回调函数逻辑处理请求
"""
class WriterNode(Node):
    """
    创建一个作家节点，并在初始化时输出一个话题
    """
    def __init__(self,name):
        super().__init__(name)
        self.get_logger().info("hello %s,I'm bot_py_node by OOP" % name)
        #2. 创建并初始化发布者 成员对象 pub_novel
        self.pub_novel=self.create_publisher(String,"Topic_test",10)

        #3. 创建发布逻辑
        self.i=0 #i 是计数器
        timer_period=1 #每5秒do something
        #启动timer 每timer_period call `timer_callback interface
        self.timer=self.create_timer(timer_period,self.timer_callback)
        
        
        #4. 创建并初始化订阅subscriber.话题类型为Uint32
        self.account=80
        self.create_subscription(UInt32,"uint32_topic_test",self.recv_money_callback,10)

        # self.create_subscription(UInt32,"topic_test2",10)
        # self.create_timer(timer_period,self.recv_money_callback)

         # 声明创建服务端 （服务接口类型，服务名字，回调函数）
        self.server_instance=self.create_service(Identify,"bot_server_interface",self.service_interface_callback);

        # params 声明参数
        self.declare_parameter("writer_timer_period",5)
    def timer_callback(self):
        """
        callback interface
        """
        
        # update param when call this
        # 通过参数名称获取目前参数值，并将其转换成 int type
        time_period=self.get_parameter("writer_timer_period").get_parameter_value().integer_value
        # 更新回调周期 修改timer 成员变量 timer_period_ns
        # ns transform s 
        self.timer.timer_period_ns=time_period* (1000*1000*1000)

        msg=String()
        msg.data='NO. %d do something %d timers' %(self.i,self.i)
        self.pub_novel.publish(msg) #执行publisher
        self.get_logger().info('I publish something "%s"' %msg.data)#logger
        self.i+=1

    def recv_money_callback(self,money):
        """
        subscriber callback
        """
        self.account+=money.data
        self.get_logger().info("received %d money"%self.account)


    # 创建服务端回调函数 包含请求和响应
    def service_interface_callback(self,request, response):
        """
        自定义服务端接口回调函数
    参数：request 客户端请求对象，携带着来自客户端的数据
         response 服务端响应，返回服务端的处理结果
    返回值：response

    request 是客户端请求对象，携带着来自客户端的数据。

    其结构就是上一节中我们所定义的name和nums组成

    response 是服务端响应，返回服务端的处理结果

    其结构由result和nums组成
        """


        # 编写回调逻辑
        self.get_logger().info("callback diy servercallback recevice: %s count： %d \n"%(request.name,self.account))
        if request.nums<=self.account*0.2:
            response.result=True
            response.nums=request.nums
            self.account=self.account-request.nums
            self.get_logger().info("get it,output %d , remaind %d" % (response.nums,self.account))
        else:
            response.result=False
            response.nums=0
            self.get_logger().info("over account")
        return response

def main(args=None):
    """
    ros2运行该节点的入口函数
    1. 导入库文件
    2. 初始化客户端库
    3. 新建节点
    4. spin循环节点
    5. 关闭客户端库
    """
    rclpy.init(args=args) # 初始化rclpy
    node = WriterNode("bot")  # 新建一个节点
    rclpy.spin(node) # 保持节点运行，检测是否收到退出指令（Ctrl+C）
    rclpy.shutdown() # 关闭rclpy





# 非OOP实现
# def main(args=None):
#     """
#     ros2运行该节点的入口函数
#     编写ROS2节点的一般步骤
#     1. 导入库文件
#     2. 初始化客户端库
#     3. 新建节点对象
#     4. spin循环节点
#     5. 关闭客户端库
#     """
#     rclpy.init(args=args) # 初始化rclpy
#     node = Node("bot_python_node")  # 新建一个节点
#     node.get_logger().info("hello I'm bot_python.")
#     rclpy.spin(node) # 保持节点运行，检测是否收到退出指令（Ctrl+C）
#     rclpy.shutdown() # 关闭rclpy